#include "drishtipaint.h"
#include "global.h"
#include "staticfunctions.h"

void
DrishtiPaint::initTagColors()
{
  uchar *colors;
  colors = new uchar[1024];

  qsrand(1);

  for(int i=0; i<256; i++)
    {
      float r,g,b,a;
      if (i > 0 && i < 254)
	{
	  r = (float)qrand()/(float)RAND_MAX;
	  g = (float)qrand()/(float)RAND_MAX;
	  b = (float)qrand()/(float)RAND_MAX;
	  a = 0.5f;
	}
      else
	{
	  r = g = b = a = 0;
	  if (i == 254)
	    {
	      r = 0; g = 0.1f; b = 0; a = 0.1f;
	    }
	}
      colors[4*i+0] = 255*r;
      colors[4*i+1] = 255*g;
      colors[4*i+2] = 255*b;
      colors[4*i+3] = 255*a;
    }
  
  Global::setTagColors(colors);
  delete [] colors;
}

DrishtiPaint::DrishtiPaint(QWidget *parent) :
  QMainWindow(parent)
{
  ui.setupUi(this);

  m_progress = new QProgressBar();
  ui.statusbar->addPermanentWidget(m_progress, 1);

  setWindowIcon(QPixmap(":/images/drishti_paint_32.png"));

  ui.menuFile->addSeparator();
  ui.tag->setValue(Global::tag());
  ui.deltaV->setValue(Global::deltaV());
  ui.deltaG->setValue(Global::deltaG());

  for (int i=0; i<Global::maxRecentFiles(); i++)
    {
      m_recentFileActions.append(new QAction(this));
      m_recentFileActions[i]->setVisible(false);
      connect(m_recentFileActions[i], SIGNAL(triggered()),
	      this, SLOT(openRecentFile()));
      ui.menuFile->addAction(m_recentFileActions[i]);
    }

  setAcceptDrops(true);

  initTagColors();

  StaticFunctions::initQColorDialog();

  m_pvlFile.clear();
  m_xmlFile.clear();

  m_tfContainer = new TransferFunctionContainer();
  m_tfManager = new TransferFunctionManager();
  m_tfManager->registerContainer(m_tfContainer);
  m_tfEditor = new TransferFunctionEditorWidget();
  m_tfEditor->setTransferFunction(NULL);    
  m_tfManager->setDisabled(true);


  m_tagColorEditor = new TagColorEditor();

  //----------------------------------------------------------
  QDockWidget *dock1 = new QDockWidget("Transfer Function Editor", this);
  dock1->setAllowedAreas(Qt::LeftDockWidgetArea | 
			 Qt::RightDockWidgetArea);
  QSplitter *splitter = new QSplitter(Qt::Vertical, dock1);
  splitter->addWidget(m_tfManager);
  splitter->addWidget(m_tfEditor);
  dock1->setWidget(splitter);
  //----------------------------------------------------------

  //----------------------------------------------------------
  QDockWidget *dock2 = new QDockWidget("Tag Color Editor", this);
  dock2->setAllowedAreas(Qt::LeftDockWidgetArea | 
			 Qt::RightDockWidgetArea);
  dock2->setWidget(m_tagColorEditor);
  dock2->hide();
  //----------------------------------------------------------

  addDockWidget(Qt::RightDockWidgetArea, dock1);
  addDockWidget(Qt::LeftDockWidgetArea, dock2);


  m_bitmapThread = new BitmapThread();

  m_volume = new Volume();
  m_volume->setBitmapThread(m_bitmapThread);

  m_slider = new MySlider();
  QVBoxLayout *slout = new QVBoxLayout();
  slout->setContentsMargins(0,0,0,0);
  ui.sliderFrame->setLayout(slout);
  ui.sliderFrame->layout()->addWidget(m_slider);


  m_imageWidget = new ImageWidget();

  QScrollArea *scrollArea = new QScrollArea;
  scrollArea->setBackgroundRole(QPalette::Dark);
  scrollArea->setWidget(m_imageWidget);

  QVBoxLayout *layout1 = new QVBoxLayout();
  layout1->setContentsMargins(0,0,0,0);
  ui.imageFrame->setLayout(layout1);
  ui.imageFrame->layout()->addWidget(scrollArea);


  ui.menuView->addAction(dock1->toggleViewAction());
  ui.menuView->addAction(dock2->toggleViewAction());
  
  connect(m_bitmapThread, SIGNAL(progressChanged(int)),
	  this, SLOT(updateProgress(int)));
  connect(m_volume, SIGNAL(progressChanged(int)),
	  this, SLOT(updateProgress(int)));
  connect(m_bitmapThread, SIGNAL(progressReset()),
	  this, SLOT(resetProgress()));
  connect(m_volume, SIGNAL(progressReset()),
	  this, SLOT(resetProgress()));

  connect(m_tfManager,
	  SIGNAL(changeTransferFunctionDisplay(int, QList<bool>)),
	  this,
	  SLOT(changeTransferFunctionDisplay(int, QList<bool>)));

  connect(m_tfManager,
	  SIGNAL(checkStateChanged(int, int, bool)),
	  this,
	  SLOT(checkStateChanged(int, int, bool)));

  connect(m_tfEditor, SIGNAL(updateComposite()),
	  this, SLOT(updateComposite()));

  connect(m_imageWidget, SIGNAL(getSlice(int)),
	  this, SLOT(getSlice(int)));  

  connect(m_imageWidget, SIGNAL(saveProject()),
	  this, SLOT(on_actionSave_triggered()));  

  connect(m_imageWidget, SIGNAL(getRawValue(int, int, int)),
	  this, SLOT(getRawValue(int, int, int)));

  connect(m_tagColorEditor, SIGNAL(tagColorChanged()),
	  m_imageWidget, SLOT(updateTagColors()));

  connect(m_slider, SIGNAL(valueChanged(int)),
	  m_imageWidget, SLOT(sliceChanged(int)));

  connect(m_slider, SIGNAL(userRangeChanged(int, int)),
	  m_imageWidget, SLOT(userRangeChanged(int, int)));

  connect(m_imageWidget, SIGNAL(fillVolume(int, int,
					   int, int,
					   int, int,
					   QList<int>,
					   bool)),
	  this, SLOT(fillVolume(int, int,
				int, int,
				int, int,
				QList<int>,
				bool)));

  connect(m_imageWidget, SIGNAL(tagDSlice(int, QImage)),
	  this, SLOT(tagDSlice(int, QImage)));

  connect(m_imageWidget, SIGNAL(tagWSlice(int, QImage)),
	  this, SLOT(tagWSlice(int, QImage)));

  connect(m_imageWidget, SIGNAL(tagHSlice(int, QImage)),
	  this, SLOT(tagHSlice(int, QImage)));

  connect(m_imageWidget, SIGNAL(tagDSlice(int, uchar*)),
	  this, SLOT(tagDSlice(int, uchar*)));

  connect(m_imageWidget, SIGNAL(tagWSlice(int, uchar*)),
	  this, SLOT(tagWSlice(int, uchar*)));

  connect(m_imageWidget, SIGNAL(tagHSlice(int, uchar*)),
	  this, SLOT(tagHSlice(int, uchar*)));

  connect(m_imageWidget, SIGNAL(tagAllVisible(int, int,
					      int, int,
					      int, int)),
	  this, SLOT(tagAllVisible(int, int,
				   int, int,
				   int, int)));

  connect(m_imageWidget, SIGNAL(dilate()),
	  this, SLOT(dilate()));
  connect(m_imageWidget, SIGNAL(dilate(int, int,
				       int, int,
				       int, int)),
	  this, SLOT(dilate(int, int,
			    int, int,
			    int, int)));

  connect(m_imageWidget, SIGNAL(erode()),
	  this, SLOT(erode()));
  connect(m_imageWidget, SIGNAL(erode(int, int,
				      int, int,
				      int, int)),
	  this, SLOT(erode(int, int,
			   int, int,
			   int, int)));


  connect(m_imageWidget, SIGNAL(setDeltaV(int)),
	  this, SLOT(setDeltaV(int)));

  connect(m_imageWidget, SIGNAL(setDeltaG(int)),
	  this, SLOT(setDeltaG(int)));

  loadSettings();
}

void DrishtiPaint::updateProgress(int val) { m_progress->setValue(val); }
void DrishtiPaint::resetProgress() { m_progress->reset(); }

void
DrishtiPaint::on_actionHelp_triggered()
{
  QString app;
#if defined(Q_OS_LINUX)
  app = 
    QLibraryInfo::location(QLibraryInfo::BinariesPath) + 
    QDir::separator() +
    QLatin1String(DRISHTIPAINT_ASSISTANT);
#elif defined(Q_OS_WIN32)
  app = QCoreApplication::applicationDirPath() + "/assistant";
#elif defined(Q_OS_MAC)
  QDir appd=QCoreApplication::applicationDirPath();
  appd.cdUp();
  appd.cdUp();
  appd.cdUp();
  appd.cd("Assistant.app");
  appd.cd("Contents");
  appd.cd("MacOS");
  
  app = appd.absoluteFilePath("Assistant");
#else
  #error Unsupported platform.
#endif

  QStringList args;
  args << "-collectionFile";
  args << QFileInfo(Global::documentationPath(),
		   "drishtipaint.qhc").absoluteFilePath();
  args << "-enableRemoteControl";

  QProcess *process = new QProcess(this);
  process->start(app, args);

  if (!process->waitForStarted())
    {
      QMessageBox::critical(this,  "Remote Control",
			    QString("Unable to launch Help."));
      return;
    }
}

void
DrishtiPaint::on_saveImage_triggered()
{
  m_imageWidget->saveImage();
}

void
DrishtiPaint::tagDSlice(int currslice, QImage usermask)
{
  m_volume->tagDSlice(currslice, usermask.bits(), false);
  getSlice(m_currSlice);
}
void
DrishtiPaint::tagWSlice(int currslice, QImage usermask)
{
  m_volume->tagWSlice(currslice, usermask.bits(), false);
  getSlice(m_currSlice);
}
void
DrishtiPaint::tagHSlice(int currslice, QImage usermask)
{
  m_volume->tagHSlice(currslice, usermask.bits(), false);
  getSlice(m_currSlice);
}


void
DrishtiPaint::tagDSlice(int currslice, uchar* tags)
{
  m_volume->tagDSlice(currslice, tags, true);
}
void
DrishtiPaint::tagWSlice(int currslice, uchar* tags)
{
  m_volume->tagWSlice(currslice, tags, true);
}
void
DrishtiPaint::tagHSlice(int currslice, uchar* tags)
{
  m_volume->tagHSlice(currslice, tags, true);
}

void
DrishtiPaint::fillVolume(int mind, int maxd,
			 int minw, int maxw,
			 int minh, int maxh,
			 QList<int> dwh,
			 bool slice)
{
  m_volume->fillVolume(mind, maxd,
		       minw, maxw,
		       minh, maxh,
		       dwh, slice);
  getSlice(m_currSlice);
}

void
DrishtiPaint::tagAllVisible(int mind, int maxd,
			    int minw, int maxw,
			    int minh, int maxh)
{
  m_volume->tagAllVisible(mind, maxd,
			  minw, maxw,
			  minh, maxh);
  getSlice(m_currSlice);
}

void
DrishtiPaint::dilate()
{
  m_volume->dilateVolume();
  getSlice(m_currSlice);  
}
void
DrishtiPaint::dilate(int mind, int maxd,
		     int minw, int maxw,
		     int minh, int maxh)
{
  m_volume->dilateVolume(mind, maxd,
			 minw, maxw,
			 minh, maxh);
  getSlice(m_currSlice);  
}

void
DrishtiPaint::erode()
{
  m_volume->erodeVolume();
  getSlice(m_currSlice);  
}
void
DrishtiPaint::erode(int mind, int maxd,
		    int minw, int maxw,
		    int minh, int maxh)
{
  m_volume->erodeVolume(mind, maxd,
			minw, maxw,
			minh, maxh);
  getSlice(m_currSlice);  
}

void
DrishtiPaint::getSlice(int slc)
{
  m_currSlice = slc;

  m_slider->setValue(slc);

  uchar *slice;
  uchar *maskslice;

  if (ui.butZ->isChecked())
    {
      slice = m_volume->getDepthSliceImage(m_currSlice);
      maskslice = m_volume->getMaskDepthSliceImage(m_currSlice);
    }
  else if (ui.butY->isChecked())
    {
      slice = m_volume->getWidthSliceImage(m_currSlice); 
      maskslice = m_volume->getMaskWidthSliceImage(m_currSlice);
    }
  else if (ui.butX->isChecked())
    {
      slice = m_volume->getHeightSliceImage(m_currSlice); 
      maskslice = m_volume->getMaskHeightSliceImage(m_currSlice);
    }

  m_imageWidget->setImage(slice, maskslice);
}

void
DrishtiPaint::on_areaTool_clicked(bool flag)
{
  ui.areaTool->setFlat(!flag);
  m_imageWidget->setAreaTool(flag);
}

void
DrishtiPaint::setDeltaV(int d)
{
  ui.deltaV->setValue(d);
  Global::setDeltaV(d);
}
void
DrishtiPaint::setDeltaG(int d)
{
  ui.deltaG->setValue(d);
  Global::setDeltaG(d);
}

void DrishtiPaint::on_tag_valueChanged(int t) { Global::setTag(t); }
void DrishtiPaint::on_deltaV_valueChanged(int d) { Global::setDeltaV(d); }
void DrishtiPaint::on_deltaG_valueChanged(int d) { Global::setDeltaG(d); }

void
DrishtiPaint::on_butZ_clicked()
{
  if (! m_volume->isValid()) return;

  m_imageWidget->setSliceType(ImageWidget::DSlice);

  int d, w, h, u0, u1;
  m_volume->gridSize(d, w, h);
  m_imageWidget->depthUserRange(u0, u1);
  m_slider->set(0, d-1, u0, u1, 0);
}
void
DrishtiPaint::on_butY_clicked()
{
  if (! m_volume->isValid()) return;

  m_imageWidget->setSliceType(ImageWidget::WSlice);

  int d, w, h, u0, u1;
  m_volume->gridSize(d, w, h);
  m_imageWidget->widthUserRange(u0, u1);
  m_slider->set(0, w-1, u0, u1, 0);
}
void
DrishtiPaint::on_butX_clicked()
{
  if (! m_volume->isValid()) return;

  m_imageWidget->setSliceType(ImageWidget::HSlice);

  int d, w, h, u0, u1;
  m_volume->gridSize(d, w, h);
  m_imageWidget->heightUserRange(u0, u1);
  m_slider->set(0, h-1, u0, u1, 0);
}


void
DrishtiPaint::getRawValue(int d, int w, int h)
{
  if (! m_volume->isValid()) return;

  m_imageWidget->setRawValue(m_volume->rawValue(d, w, h));
}

void
DrishtiPaint::on_actionLoad_triggered()
{
  QString flnm;
  flnm = QFileDialog::getOpenFileName(0,
				      "Load Processed Volume or Project File",
				      Global::previousDirectory(),
				      "PVL/XML Files (*.pvl.nc | *.xml)");
  
  if (flnm.isEmpty())
    return;

  setFile(flnm);
}

void
DrishtiPaint::on_actionExit_triggered()
{
  m_volume->reset();
  saveSettings();
  close();
}
void
DrishtiPaint::closeEvent(QCloseEvent *)
{
  on_actionExit_triggered();
}


void
DrishtiPaint::updateComposite()
{
  QImage colorMap = m_tfContainer->composite(0);
  m_imageWidget->loadLookupTable(colorMap);

  m_volume->createBitmask();
}

void
DrishtiPaint::changeTransferFunctionDisplay(int tfnum, QList<bool> on)
{
  if (tfnum >= 0)
    {
      SplineTransferFunction *sptr = m_tfContainer->transferFunctionPtr(tfnum);
      m_tfEditor->setTransferFunction(sptr);
    }
  else
    m_tfEditor->setTransferFunction(NULL);    

  updateComposite();
}

void
DrishtiPaint::checkStateChanged(int i, int j, bool flag)
{
  updateComposite();
}

void
DrishtiPaint::dragEnterEvent(QDragEnterEvent *event)
{
  if (event && event->mimeData())
    {
      const QMimeData *data = event->mimeData();
      if (data->hasUrls())
	{
	  QList<QUrl> urls = data->urls();

	  if (StaticFunctions::checkURLs(urls, ".pvl.nc") ||
	      StaticFunctions::checkURLs(urls, ".xml"))
	    event->acceptProposedAction();
	}
    }
}

void
DrishtiPaint::dropEvent(QDropEvent *event)
{
  if (event && event->mimeData())
    {
      const QMimeData *data = event->mimeData();
      if (data->hasUrls())
	{
	  QUrl url = data->urls()[0];
	  QFileInfo info(url.toLocalFile());
	  if (info.exists() && info.isFile())
	    {
	      if (StaticFunctions::checkExtension(url.toLocalFile(), ".pvl.nc") ||
		  StaticFunctions::checkExtension(url.toLocalFile(), ".xml"))
		{
		  QString flnm = (data->urls())[0].toLocalFile();
		  setFile(flnm);
		}
	    }
	}
    }
}

void
DrishtiPaint::setFile(QString filename)
{
  QString flnm;

  if (StaticFunctions::checkExtension(filename, ".pvl.nc"))
    {
      flnm = filename;
      m_tfEditor->setTransferFunction(NULL);
      m_tfManager->clearManager();
    }
  else
    {
      flnm = loadVolumeFromProject(filename.toAscii().data());

      if (flnm.isEmpty())
	{
	  QMessageBox::critical(0, "Error",
				"No volumes found in the project");
	  return;
	}
    }

  m_volume->reset();
  m_imageWidget->setGridSize(0,0,0);

  if (m_volume->setFile(flnm) == false)
    {
      QMessageBox::critical(0, "Error", "Cannot load "+flnm);
      return;
    }


  int d, w, h;
  m_volume->gridSize(d, w, h);
  m_imageWidget->setGridSize(d, w, h);

  ui.butZ->setChecked(true);
  m_slider->set(0, d-1, 0, d-1, 0);

  m_imageWidget->setSliceType(ImageWidget::DSlice);

  m_tfManager->setDisabled(false);

  m_tfEditor->setHistogramImage(m_volume->histogramImage1D(),
				m_volume->histogramImage2D());

  QFileInfo f(filename);
  Global::setPreviousDirectory(f.absolutePath());
  Global::addRecentFile(filename);
  updateRecentFileAction();

      
  if (StaticFunctions::checkExtension(filename, ".xml"))
    {
      m_tfManager->load(filename.toAscii().data());
      m_pvlFile = flnm;
      m_xmlFile = filename;
    }
  else
    {
      m_pvlFile = flnm;
      m_xmlFile.clear();
    }
}

void
DrishtiPaint::loadSettings()
{
  QString homePath = QDir::homePath();
  QFileInfo settingsFile(homePath, ".drishti.paint");
  QString flnm = settingsFile.absoluteFilePath();  

  if (! settingsFile.exists())
    return;

  QDomDocument document;
  QFile f(flnm.toAscii().data());
  if (f.open(QIODevice::ReadOnly))
    {
      document.setContent(&f);
      f.close();
    }

  QDomElement main = document.documentElement();
  QDomNodeList dlist = main.childNodes();
  for(int i=0; i<dlist.count(); i++)
    {
      if (dlist.at(i).nodeName() == "previousdirectory")
	{
	  QString str = dlist.at(i).toElement().text();
	  Global::setPreviousDirectory(str);
	}
      else if (dlist.at(i).nodeName() == "recentfile")
	{
	  QString str = dlist.at(i).toElement().text();
	  Global::addRecentFile(str);
	}
      else if (dlist.at(i).nodeName() == "tagcolors")
	{
	  QString str = dlist.at(i).toElement().text();
	  QStringList col = str.split("\n",
				      QString::SkipEmptyParts);
	  uchar *colors = Global::tagColors();
	  for(int i=0; i<qMin(256, col.size()); i++)
	    {
	      QStringList clr = col[i].split(" ",
					     QString::SkipEmptyParts);
	      colors[4*i+0] = clr[0].toInt();
	      colors[4*i+1] = clr[1].toInt();
	      colors[4*i+2] = clr[2].toInt();
	      colors[4*i+3] = clr[3].toInt();
	    }
	  Global::setTagColors(colors);
	  m_tagColorEditor->setColors();
	}
    }

  updateRecentFileAction();
}

void
DrishtiPaint::saveSettings()
{
  QString str;
  QDomDocument doc("Drishti_Paint_v1.0");

  QDomElement topElement = doc.createElement("DrishtiPaintSettings");
  doc.appendChild(topElement);

  {
    QDomElement de0 = doc.createElement("previousdirectory");
    QDomText tn0;
    tn0 = doc.createTextNode(Global::previousDirectory());
    de0.appendChild(tn0);
    topElement.appendChild(de0);
  }

  {
    QStringList rf = Global::recentFiles();
    for (int i=0; i<rf.count(); i++)
      {
	QDomElement de0 = doc.createElement("recentfile");
	QDomText tn0;
	tn0 = doc.createTextNode(rf[i]);
	de0.appendChild(tn0);
	topElement.appendChild(de0);
      }
  }

  {
    QDomElement de0 = doc.createElement("tagcolors");
    QString str;
    uchar *colors = Global::tagColors();
    for(int i=0; i<256; i++)
      {
	if (i > 0) str += "               ";
	str += QString(" %1 %2 %3 %4\n").\
	              arg(colors[4*i+0]).\
	              arg(colors[4*i+1]).\
	              arg(colors[4*i+2]).\
	              arg(colors[4*i+3]);
      }
    QDomText tn0 = doc.createTextNode(str);
    de0.appendChild(tn0);
    topElement.appendChild(de0);
  }

  QString homePath = QDir::homePath();
  QFileInfo settingsFile(homePath, ".drishti.paint");
  QString flnm = settingsFile.absoluteFilePath();  

  QFile f(flnm.toAscii().data());
  if (f.open(QIODevice::WriteOnly))
    {
      QTextStream out(&f);
      doc.save(out, 2);
      f.close();
    }
  else
    QMessageBox::information(0, "Cannot save ", flnm.toAscii().data());
}

void
DrishtiPaint::updateRecentFileAction()
{
  QStringList rf = Global::recentFiles();
  for(int i=0; i<rf.count(); i++)
    {
      QString flnm = QFileInfo(rf[i]).fileName();
      QString text = QString("&%1. %2").arg(i+1).arg(flnm);
      m_recentFileActions[i]->setText(text);
      m_recentFileActions[i]->setData(rf[i]);
      m_recentFileActions[i]->setVisible(true);
    }
  for(int i=rf.count(); i<Global::maxRecentFiles(); i++)
    m_recentFileActions[i]->setVisible(false);

}

void
DrishtiPaint::openRecentFile()
{
  QAction *action = qobject_cast<QAction *>(sender());
  if (action)
    {
      QString filename = action->data().toString();
      QFileInfo fileInfo(filename);
      if (! fileInfo.exists())
	{
	  QMessageBox::information(0, "Error",
				   QString("Cannot locate ") +
				   filename +
				   QString(" for loading"));
	  return;
	}

      if (StaticFunctions::checkExtension(filename, ".pvl.nc") ||
	  StaticFunctions::checkExtension(filename, ".xml"))
	setFile(filename);
    }
}

QString
DrishtiPaint::loadVolumeFromProject(const char *flnm)
{
  QDomDocument document;
  QFile f(flnm);
  if (f.open(QIODevice::ReadOnly))
    {
      document.setContent(&f);
      f.close();
    }

  QDomElement main = document.documentElement();
  QDomNodeList dlist = main.childNodes();
  for(int i=0; i<dlist.count(); i++)
    {
      if (dlist.at(i).nodeName() == "volumetype")
	{
	  QString str = dlist.at(i).toElement().text();
	  if (str != "single")
	    {
	      QMessageBox::critical(0, "Error",
		QString("volumetype must be single.\n  found %1").arg(str));
	      return "";
	    }
	}
      else if (dlist.at(i).nodeName() == "volumefiles")
	{
	  // for loading volume file names with relative path
	  QFileInfo fileInfo(flnm);
	  QDir direc = fileInfo.absoluteDir();

	  QDomNodeList vlist = dlist.at(i).childNodes();
	  
	  // take only the first file
	  QString str = vlist.at(0).toElement().text();
	  QString vfile = direc.absoluteFilePath(str);

	  if (vlist.count() > 1)
	    QMessageBox::information(0, "Volume series",
	       QString("Choosing only first volume\n %1 volumes in the list").arg(vlist.count()));

	  return vfile;
	}
    }

  return "";
}

void
DrishtiPaint::on_actionSave_triggered()
{
  QString flnm;
  flnm = QFileDialog::getSaveFileName(0,
				      "Save Project File",
				      Global::previousDirectory(),
				      "XML Files (*.xml)");
  
  if (flnm.isEmpty())
    return;

  saveProject(flnm.toAscii().data());
}

void
DrishtiPaint::saveProject(const char* flnm)
{ 
  QDomDocument doc;
  QDomElement topElement;

  {
    QFile f(flnm);
    if (f.open(QIODevice::ReadOnly))
      {
	doc.setContent(&f);
	f.close();

	topElement = doc.documentElement();

	QDomNodeList dlist = topElement.childNodes();
	for(int i=0; i<dlist.count(); i++)
	  {
	    if (dlist.at(i).nodeName() == "volumetype")
	      topElement.removeChild(dlist.at(i));

	    if (dlist.at(i).nodeName() == "volumefiles")
	      topElement.removeChild(dlist.at(i));

	    if (dlist.at(i).nodeName() == "transferfunction")
	      topElement.removeChild(dlist.at(i));
	  }
      }
    else
      {
	doc = QDomDocument("Drishti_v1.0");	
	topElement = doc.createElement("Drishti");
	doc.appendChild(topElement);
      }    
  }


  {
    QDomElement de0 = doc.createElement("volumetype");
    QDomText tn0 = doc.createTextNode("single");
    de0.appendChild(tn0);
    topElement.appendChild(de0);
  }

  {
    // for saving volume file names with relative path
    QFileInfo fileInfo(flnm);
    QDir direc = fileInfo.absoluteDir();

    QDomElement dev = doc.createElement("volumefiles");
    QList<QString> files;
    QDomElement de0 = doc.createElement("name");
    // saving volume filenames relative to the project file path
    QString relFile = direc.relativeFilePath(m_pvlFile);
    QDomText tn0 = doc.createTextNode(relFile);
    de0.appendChild(tn0);
    dev.appendChild(de0);
    topElement.appendChild(dev);
  }

  {
    QFile f(flnm);
    if (f.open(QIODevice::WriteOnly))
      {
	QTextStream out(&f);
	doc.save(out, 2);
	f.close();
      }
  }

  //m_preferencesWidget->save(flnm);
  m_tfManager->save(flnm);

  QFileInfo f(flnm);
  Global::setPreviousDirectory(f.absolutePath());

  QMessageBox::information(0, "Save Project", "Project saved");
}

void
DrishtiPaint::keyPressEvent(QKeyEvent *event)
{
  // pass all keypressevents on to image widget
  m_imageWidget->keyPressEvent(event);
}
